//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift Atomics open source project
//
// Copyright (c) 2020-2021 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

// #############################################################################
// #                                                                           #
// #            DO NOT EDIT THIS FILE; IT IS AUTOGENERATED.                    #
// #                                                                           #
// #############################################################################


import _AtomicsShims

extension Int: AtomicValue {
  @frozen
  public struct AtomicRepresentation {
    public typealias Value = Int

    @usableFromInline
    var _storage: _AtomicIntStorage

    @inline(__always) @_alwaysEmitIntoClient
    public init(_ value: Value) {
      self._storage = _sa_prepare_Int(value)
    }

    @inline(__always) @_alwaysEmitIntoClient
    public func dispose() -> Value {
      return _sa_dispose_Int(_storage)
    }
  }
}

extension UnsafeMutablePointer
where Pointee == Int.AtomicRepresentation {
  @inlinable @inline(__always)
  internal var _extract: UnsafeMutablePointer<_AtomicIntStorage> {
    // `Int` is layout-compatible with its only stored property.
    return UnsafeMutableRawPointer(self)
      .assumingMemoryBound(to: _AtomicIntStorage.self)
  }
}

extension Int.AtomicRepresentation: AtomicStorage {
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicLoad(
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicLoadOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_load_relaxed_Int(pointer._extract)
    case .acquiring:
      return _sa_load_acquire_Int(pointer._extract)
    case .sequentiallyConsistent:
      return _sa_load_seq_cst_Int(pointer._extract)
    default:
      fatalError("Unsupported ordering")
    }
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicStore(
    _ desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicStoreOrdering
  ) {
    switch ordering {
    case .relaxed:
      _sa_store_relaxed_Int(pointer._extract, desired)
    case .releasing:
      _sa_store_release_Int(pointer._extract, desired)
    case .sequentiallyConsistent:
      _sa_store_seq_cst_Int(pointer._extract, desired)
    default:
      fatalError("Unsupported ordering")
    }
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicExchange(
    _ desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_exchange_relaxed_Int(pointer._extract, desired)
    case .acquiring:
      return _sa_exchange_acquire_Int(pointer._extract, desired)
    case .releasing:
      return _sa_exchange_release_Int(pointer._extract, desired)
    case .acquiringAndReleasing:
      return _sa_exchange_acq_rel_Int(pointer._extract, desired)
    case .sequentiallyConsistent:
      return _sa_exchange_seq_cst_Int(pointer._extract, desired)
    default:
      fatalError("Unsupported ordering")
    }
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicCompareExchange(
    expected: Value,
    desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> (exchanged: Bool, original: Value) {
    var expected = expected
    let exchanged: Bool
    switch ordering {
    case .relaxed:
      exchanged = _sa_cmpxchg_strong_relaxed_relaxed_Int(
        pointer._extract,
        &expected, desired)
    case .acquiring:
      exchanged = _sa_cmpxchg_strong_acquire_acquire_Int(
        pointer._extract,
        &expected, desired)
    case .releasing:
      exchanged = _sa_cmpxchg_strong_release_relaxed_Int(
        pointer._extract,
        &expected, desired)
    case .acquiringAndReleasing:
      exchanged = _sa_cmpxchg_strong_acq_rel_acquire_Int(
        pointer._extract,
        &expected, desired)
    case .sequentiallyConsistent:
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_Int(
        pointer._extract,
        &expected, desired)
    default:
      fatalError("Unsupported ordering")
    }
    return (exchanged, expected)
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicCompareExchange(
    expected: Value,
    desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    successOrdering: AtomicUpdateOrdering,
    failureOrdering: AtomicLoadOrdering
  ) -> (exchanged: Bool, original: Value) {
    var expected = expected
    let exchanged: Bool
    // FIXME: stdatomic.h (and LLVM underneath) doesn't support
    // arbitrary ordering combinations yet, so upgrade the success
    // ordering when necessary so that it is at least as "strong" as
    // the failure case.
    switch (successOrdering, failureOrdering) {
    case (.relaxed, .relaxed):
      exchanged = _sa_cmpxchg_strong_relaxed_relaxed_Int(
        pointer._extract,
        &expected,
        desired)
    case (.relaxed, .acquiring):
      exchanged = _sa_cmpxchg_strong_acquire_acquire_Int(
        pointer._extract,
        &expected,
        desired)
    case (.relaxed, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_Int(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .relaxed):
      exchanged = _sa_cmpxchg_strong_acquire_relaxed_Int(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .acquiring):
      exchanged = _sa_cmpxchg_strong_acquire_acquire_Int(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_Int(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .relaxed):
      exchanged = _sa_cmpxchg_strong_release_relaxed_Int(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .acquiring):
      exchanged = _sa_cmpxchg_strong_acq_rel_acquire_Int(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_Int(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .relaxed):
      exchanged = _sa_cmpxchg_strong_acq_rel_relaxed_Int(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .acquiring):
      exchanged = _sa_cmpxchg_strong_acq_rel_acquire_Int(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_Int(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .relaxed):
      exchanged = _sa_cmpxchg_strong_seq_cst_relaxed_Int(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .acquiring):
      exchanged = _sa_cmpxchg_strong_seq_cst_acquire_Int(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_Int(
        pointer._extract,
        &expected,
        desired)
    default:
      fatalError("Unsupported ordering")
    }
    return (exchanged, expected)
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicWeakCompareExchange(
    expected: Value,
    desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    successOrdering: AtomicUpdateOrdering,
    failureOrdering: AtomicLoadOrdering
  ) -> (exchanged: Bool, original: Value) {
    var expected = expected
    let exchanged: Bool
    // FIXME: stdatomic.h (and LLVM underneath) doesn't support
    // arbitrary ordering combinations yet, so upgrade the success
    // ordering when necessary so that it is at least as "strong" as
    // the failure case.
    switch (successOrdering, failureOrdering) {
    case (.relaxed, .relaxed):
      exchanged = _sa_cmpxchg_weak_relaxed_relaxed_Int(
        pointer._extract,
        &expected,
        desired)
    case (.relaxed, .acquiring):
      exchanged = _sa_cmpxchg_weak_acquire_acquire_Int(
        pointer._extract,
        &expected,
        desired)
    case (.relaxed, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_Int(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .relaxed):
      exchanged = _sa_cmpxchg_weak_acquire_relaxed_Int(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .acquiring):
      exchanged = _sa_cmpxchg_weak_acquire_acquire_Int(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_Int(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .relaxed):
      exchanged = _sa_cmpxchg_weak_release_relaxed_Int(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .acquiring):
      exchanged = _sa_cmpxchg_weak_acq_rel_acquire_Int(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_Int(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .relaxed):
      exchanged = _sa_cmpxchg_weak_acq_rel_relaxed_Int(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .acquiring):
      exchanged = _sa_cmpxchg_weak_acq_rel_acquire_Int(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_Int(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .relaxed):
      exchanged = _sa_cmpxchg_weak_seq_cst_relaxed_Int(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .acquiring):
      exchanged = _sa_cmpxchg_weak_seq_cst_acquire_Int(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_Int(
        pointer._extract,
        &expected,
        desired)
    default:
      fatalError("Unsupported ordering")
    }
    return (exchanged, expected)
  }
}

extension Int: AtomicInteger {}

extension Int.AtomicRepresentation: AtomicIntegerStorage {
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenWrappingIncrement(
    by operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_add_relaxed_Int(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_add_acquire_Int(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_add_release_Int(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_add_acq_rel_Int(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_add_seq_cst_Int(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenWrappingDecrement(
    by operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_sub_relaxed_Int(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_sub_acquire_Int(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_sub_release_Int(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_sub_acq_rel_Int(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_sub_seq_cst_Int(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenBitwiseAnd(
    with operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_and_relaxed_Int(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_and_acquire_Int(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_and_release_Int(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_and_acq_rel_Int(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_and_seq_cst_Int(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenBitwiseOr(
    with operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_or_relaxed_Int(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_or_acquire_Int(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_or_release_Int(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_or_acq_rel_Int(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_or_seq_cst_Int(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenBitwiseXor(
    with operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_xor_relaxed_Int(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_xor_acquire_Int(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_xor_release_Int(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_xor_acq_rel_Int(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_xor_seq_cst_Int(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
}

extension Int64: AtomicValue {
  @frozen
  public struct AtomicRepresentation {
    public typealias Value = Int64

    @usableFromInline
    var _storage: _AtomicInt64Storage

    @inline(__always) @_alwaysEmitIntoClient
    public init(_ value: Value) {
      self._storage = _sa_prepare_Int64(value)
    }

    @inline(__always) @_alwaysEmitIntoClient
    public func dispose() -> Value {
      return _sa_dispose_Int64(_storage)
    }
  }
}

extension UnsafeMutablePointer
where Pointee == Int64.AtomicRepresentation {
  @inlinable @inline(__always)
  internal var _extract: UnsafeMutablePointer<_AtomicInt64Storage> {
    // `Int64` is layout-compatible with its only stored property.
    return UnsafeMutableRawPointer(self)
      .assumingMemoryBound(to: _AtomicInt64Storage.self)
  }
}

extension Int64.AtomicRepresentation: AtomicStorage {
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicLoad(
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicLoadOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_load_relaxed_Int64(pointer._extract)
    case .acquiring:
      return _sa_load_acquire_Int64(pointer._extract)
    case .sequentiallyConsistent:
      return _sa_load_seq_cst_Int64(pointer._extract)
    default:
      fatalError("Unsupported ordering")
    }
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicStore(
    _ desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicStoreOrdering
  ) {
    switch ordering {
    case .relaxed:
      _sa_store_relaxed_Int64(pointer._extract, desired)
    case .releasing:
      _sa_store_release_Int64(pointer._extract, desired)
    case .sequentiallyConsistent:
      _sa_store_seq_cst_Int64(pointer._extract, desired)
    default:
      fatalError("Unsupported ordering")
    }
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicExchange(
    _ desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_exchange_relaxed_Int64(pointer._extract, desired)
    case .acquiring:
      return _sa_exchange_acquire_Int64(pointer._extract, desired)
    case .releasing:
      return _sa_exchange_release_Int64(pointer._extract, desired)
    case .acquiringAndReleasing:
      return _sa_exchange_acq_rel_Int64(pointer._extract, desired)
    case .sequentiallyConsistent:
      return _sa_exchange_seq_cst_Int64(pointer._extract, desired)
    default:
      fatalError("Unsupported ordering")
    }
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicCompareExchange(
    expected: Value,
    desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> (exchanged: Bool, original: Value) {
    var expected = expected
    let exchanged: Bool
    switch ordering {
    case .relaxed:
      exchanged = _sa_cmpxchg_strong_relaxed_relaxed_Int64(
        pointer._extract,
        &expected, desired)
    case .acquiring:
      exchanged = _sa_cmpxchg_strong_acquire_acquire_Int64(
        pointer._extract,
        &expected, desired)
    case .releasing:
      exchanged = _sa_cmpxchg_strong_release_relaxed_Int64(
        pointer._extract,
        &expected, desired)
    case .acquiringAndReleasing:
      exchanged = _sa_cmpxchg_strong_acq_rel_acquire_Int64(
        pointer._extract,
        &expected, desired)
    case .sequentiallyConsistent:
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_Int64(
        pointer._extract,
        &expected, desired)
    default:
      fatalError("Unsupported ordering")
    }
    return (exchanged, expected)
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicCompareExchange(
    expected: Value,
    desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    successOrdering: AtomicUpdateOrdering,
    failureOrdering: AtomicLoadOrdering
  ) -> (exchanged: Bool, original: Value) {
    var expected = expected
    let exchanged: Bool
    // FIXME: stdatomic.h (and LLVM underneath) doesn't support
    // arbitrary ordering combinations yet, so upgrade the success
    // ordering when necessary so that it is at least as "strong" as
    // the failure case.
    switch (successOrdering, failureOrdering) {
    case (.relaxed, .relaxed):
      exchanged = _sa_cmpxchg_strong_relaxed_relaxed_Int64(
        pointer._extract,
        &expected,
        desired)
    case (.relaxed, .acquiring):
      exchanged = _sa_cmpxchg_strong_acquire_acquire_Int64(
        pointer._extract,
        &expected,
        desired)
    case (.relaxed, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_Int64(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .relaxed):
      exchanged = _sa_cmpxchg_strong_acquire_relaxed_Int64(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .acquiring):
      exchanged = _sa_cmpxchg_strong_acquire_acquire_Int64(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_Int64(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .relaxed):
      exchanged = _sa_cmpxchg_strong_release_relaxed_Int64(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .acquiring):
      exchanged = _sa_cmpxchg_strong_acq_rel_acquire_Int64(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_Int64(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .relaxed):
      exchanged = _sa_cmpxchg_strong_acq_rel_relaxed_Int64(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .acquiring):
      exchanged = _sa_cmpxchg_strong_acq_rel_acquire_Int64(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_Int64(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .relaxed):
      exchanged = _sa_cmpxchg_strong_seq_cst_relaxed_Int64(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .acquiring):
      exchanged = _sa_cmpxchg_strong_seq_cst_acquire_Int64(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_Int64(
        pointer._extract,
        &expected,
        desired)
    default:
      fatalError("Unsupported ordering")
    }
    return (exchanged, expected)
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicWeakCompareExchange(
    expected: Value,
    desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    successOrdering: AtomicUpdateOrdering,
    failureOrdering: AtomicLoadOrdering
  ) -> (exchanged: Bool, original: Value) {
    var expected = expected
    let exchanged: Bool
    // FIXME: stdatomic.h (and LLVM underneath) doesn't support
    // arbitrary ordering combinations yet, so upgrade the success
    // ordering when necessary so that it is at least as "strong" as
    // the failure case.
    switch (successOrdering, failureOrdering) {
    case (.relaxed, .relaxed):
      exchanged = _sa_cmpxchg_weak_relaxed_relaxed_Int64(
        pointer._extract,
        &expected,
        desired)
    case (.relaxed, .acquiring):
      exchanged = _sa_cmpxchg_weak_acquire_acquire_Int64(
        pointer._extract,
        &expected,
        desired)
    case (.relaxed, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_Int64(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .relaxed):
      exchanged = _sa_cmpxchg_weak_acquire_relaxed_Int64(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .acquiring):
      exchanged = _sa_cmpxchg_weak_acquire_acquire_Int64(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_Int64(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .relaxed):
      exchanged = _sa_cmpxchg_weak_release_relaxed_Int64(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .acquiring):
      exchanged = _sa_cmpxchg_weak_acq_rel_acquire_Int64(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_Int64(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .relaxed):
      exchanged = _sa_cmpxchg_weak_acq_rel_relaxed_Int64(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .acquiring):
      exchanged = _sa_cmpxchg_weak_acq_rel_acquire_Int64(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_Int64(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .relaxed):
      exchanged = _sa_cmpxchg_weak_seq_cst_relaxed_Int64(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .acquiring):
      exchanged = _sa_cmpxchg_weak_seq_cst_acquire_Int64(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_Int64(
        pointer._extract,
        &expected,
        desired)
    default:
      fatalError("Unsupported ordering")
    }
    return (exchanged, expected)
  }
}

extension Int64: AtomicInteger {}

extension Int64.AtomicRepresentation: AtomicIntegerStorage {
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenWrappingIncrement(
    by operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_add_relaxed_Int64(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_add_acquire_Int64(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_add_release_Int64(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_add_acq_rel_Int64(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_add_seq_cst_Int64(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenWrappingDecrement(
    by operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_sub_relaxed_Int64(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_sub_acquire_Int64(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_sub_release_Int64(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_sub_acq_rel_Int64(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_sub_seq_cst_Int64(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenBitwiseAnd(
    with operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_and_relaxed_Int64(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_and_acquire_Int64(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_and_release_Int64(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_and_acq_rel_Int64(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_and_seq_cst_Int64(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenBitwiseOr(
    with operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_or_relaxed_Int64(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_or_acquire_Int64(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_or_release_Int64(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_or_acq_rel_Int64(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_or_seq_cst_Int64(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenBitwiseXor(
    with operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_xor_relaxed_Int64(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_xor_acquire_Int64(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_xor_release_Int64(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_xor_acq_rel_Int64(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_xor_seq_cst_Int64(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
}

extension Int32: AtomicValue {
  @frozen
  public struct AtomicRepresentation {
    public typealias Value = Int32

    @usableFromInline
    var _storage: _AtomicInt32Storage

    @inline(__always) @_alwaysEmitIntoClient
    public init(_ value: Value) {
      self._storage = _sa_prepare_Int32(value)
    }

    @inline(__always) @_alwaysEmitIntoClient
    public func dispose() -> Value {
      return _sa_dispose_Int32(_storage)
    }
  }
}

extension UnsafeMutablePointer
where Pointee == Int32.AtomicRepresentation {
  @inlinable @inline(__always)
  internal var _extract: UnsafeMutablePointer<_AtomicInt32Storage> {
    // `Int32` is layout-compatible with its only stored property.
    return UnsafeMutableRawPointer(self)
      .assumingMemoryBound(to: _AtomicInt32Storage.self)
  }
}

extension Int32.AtomicRepresentation: AtomicStorage {
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicLoad(
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicLoadOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_load_relaxed_Int32(pointer._extract)
    case .acquiring:
      return _sa_load_acquire_Int32(pointer._extract)
    case .sequentiallyConsistent:
      return _sa_load_seq_cst_Int32(pointer._extract)
    default:
      fatalError("Unsupported ordering")
    }
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicStore(
    _ desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicStoreOrdering
  ) {
    switch ordering {
    case .relaxed:
      _sa_store_relaxed_Int32(pointer._extract, desired)
    case .releasing:
      _sa_store_release_Int32(pointer._extract, desired)
    case .sequentiallyConsistent:
      _sa_store_seq_cst_Int32(pointer._extract, desired)
    default:
      fatalError("Unsupported ordering")
    }
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicExchange(
    _ desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_exchange_relaxed_Int32(pointer._extract, desired)
    case .acquiring:
      return _sa_exchange_acquire_Int32(pointer._extract, desired)
    case .releasing:
      return _sa_exchange_release_Int32(pointer._extract, desired)
    case .acquiringAndReleasing:
      return _sa_exchange_acq_rel_Int32(pointer._extract, desired)
    case .sequentiallyConsistent:
      return _sa_exchange_seq_cst_Int32(pointer._extract, desired)
    default:
      fatalError("Unsupported ordering")
    }
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicCompareExchange(
    expected: Value,
    desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> (exchanged: Bool, original: Value) {
    var expected = expected
    let exchanged: Bool
    switch ordering {
    case .relaxed:
      exchanged = _sa_cmpxchg_strong_relaxed_relaxed_Int32(
        pointer._extract,
        &expected, desired)
    case .acquiring:
      exchanged = _sa_cmpxchg_strong_acquire_acquire_Int32(
        pointer._extract,
        &expected, desired)
    case .releasing:
      exchanged = _sa_cmpxchg_strong_release_relaxed_Int32(
        pointer._extract,
        &expected, desired)
    case .acquiringAndReleasing:
      exchanged = _sa_cmpxchg_strong_acq_rel_acquire_Int32(
        pointer._extract,
        &expected, desired)
    case .sequentiallyConsistent:
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_Int32(
        pointer._extract,
        &expected, desired)
    default:
      fatalError("Unsupported ordering")
    }
    return (exchanged, expected)
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicCompareExchange(
    expected: Value,
    desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    successOrdering: AtomicUpdateOrdering,
    failureOrdering: AtomicLoadOrdering
  ) -> (exchanged: Bool, original: Value) {
    var expected = expected
    let exchanged: Bool
    // FIXME: stdatomic.h (and LLVM underneath) doesn't support
    // arbitrary ordering combinations yet, so upgrade the success
    // ordering when necessary so that it is at least as "strong" as
    // the failure case.
    switch (successOrdering, failureOrdering) {
    case (.relaxed, .relaxed):
      exchanged = _sa_cmpxchg_strong_relaxed_relaxed_Int32(
        pointer._extract,
        &expected,
        desired)
    case (.relaxed, .acquiring):
      exchanged = _sa_cmpxchg_strong_acquire_acquire_Int32(
        pointer._extract,
        &expected,
        desired)
    case (.relaxed, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_Int32(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .relaxed):
      exchanged = _sa_cmpxchg_strong_acquire_relaxed_Int32(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .acquiring):
      exchanged = _sa_cmpxchg_strong_acquire_acquire_Int32(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_Int32(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .relaxed):
      exchanged = _sa_cmpxchg_strong_release_relaxed_Int32(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .acquiring):
      exchanged = _sa_cmpxchg_strong_acq_rel_acquire_Int32(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_Int32(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .relaxed):
      exchanged = _sa_cmpxchg_strong_acq_rel_relaxed_Int32(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .acquiring):
      exchanged = _sa_cmpxchg_strong_acq_rel_acquire_Int32(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_Int32(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .relaxed):
      exchanged = _sa_cmpxchg_strong_seq_cst_relaxed_Int32(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .acquiring):
      exchanged = _sa_cmpxchg_strong_seq_cst_acquire_Int32(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_Int32(
        pointer._extract,
        &expected,
        desired)
    default:
      fatalError("Unsupported ordering")
    }
    return (exchanged, expected)
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicWeakCompareExchange(
    expected: Value,
    desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    successOrdering: AtomicUpdateOrdering,
    failureOrdering: AtomicLoadOrdering
  ) -> (exchanged: Bool, original: Value) {
    var expected = expected
    let exchanged: Bool
    // FIXME: stdatomic.h (and LLVM underneath) doesn't support
    // arbitrary ordering combinations yet, so upgrade the success
    // ordering when necessary so that it is at least as "strong" as
    // the failure case.
    switch (successOrdering, failureOrdering) {
    case (.relaxed, .relaxed):
      exchanged = _sa_cmpxchg_weak_relaxed_relaxed_Int32(
        pointer._extract,
        &expected,
        desired)
    case (.relaxed, .acquiring):
      exchanged = _sa_cmpxchg_weak_acquire_acquire_Int32(
        pointer._extract,
        &expected,
        desired)
    case (.relaxed, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_Int32(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .relaxed):
      exchanged = _sa_cmpxchg_weak_acquire_relaxed_Int32(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .acquiring):
      exchanged = _sa_cmpxchg_weak_acquire_acquire_Int32(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_Int32(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .relaxed):
      exchanged = _sa_cmpxchg_weak_release_relaxed_Int32(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .acquiring):
      exchanged = _sa_cmpxchg_weak_acq_rel_acquire_Int32(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_Int32(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .relaxed):
      exchanged = _sa_cmpxchg_weak_acq_rel_relaxed_Int32(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .acquiring):
      exchanged = _sa_cmpxchg_weak_acq_rel_acquire_Int32(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_Int32(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .relaxed):
      exchanged = _sa_cmpxchg_weak_seq_cst_relaxed_Int32(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .acquiring):
      exchanged = _sa_cmpxchg_weak_seq_cst_acquire_Int32(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_Int32(
        pointer._extract,
        &expected,
        desired)
    default:
      fatalError("Unsupported ordering")
    }
    return (exchanged, expected)
  }
}

extension Int32: AtomicInteger {}

extension Int32.AtomicRepresentation: AtomicIntegerStorage {
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenWrappingIncrement(
    by operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_add_relaxed_Int32(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_add_acquire_Int32(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_add_release_Int32(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_add_acq_rel_Int32(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_add_seq_cst_Int32(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenWrappingDecrement(
    by operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_sub_relaxed_Int32(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_sub_acquire_Int32(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_sub_release_Int32(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_sub_acq_rel_Int32(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_sub_seq_cst_Int32(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenBitwiseAnd(
    with operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_and_relaxed_Int32(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_and_acquire_Int32(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_and_release_Int32(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_and_acq_rel_Int32(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_and_seq_cst_Int32(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenBitwiseOr(
    with operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_or_relaxed_Int32(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_or_acquire_Int32(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_or_release_Int32(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_or_acq_rel_Int32(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_or_seq_cst_Int32(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenBitwiseXor(
    with operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_xor_relaxed_Int32(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_xor_acquire_Int32(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_xor_release_Int32(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_xor_acq_rel_Int32(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_xor_seq_cst_Int32(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
}

extension Int16: AtomicValue {
  @frozen
  public struct AtomicRepresentation {
    public typealias Value = Int16

    @usableFromInline
    var _storage: _AtomicInt16Storage

    @inline(__always) @_alwaysEmitIntoClient
    public init(_ value: Value) {
      self._storage = _sa_prepare_Int16(value)
    }

    @inline(__always) @_alwaysEmitIntoClient
    public func dispose() -> Value {
      return _sa_dispose_Int16(_storage)
    }
  }
}

extension UnsafeMutablePointer
where Pointee == Int16.AtomicRepresentation {
  @inlinable @inline(__always)
  internal var _extract: UnsafeMutablePointer<_AtomicInt16Storage> {
    // `Int16` is layout-compatible with its only stored property.
    return UnsafeMutableRawPointer(self)
      .assumingMemoryBound(to: _AtomicInt16Storage.self)
  }
}

extension Int16.AtomicRepresentation: AtomicStorage {
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicLoad(
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicLoadOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_load_relaxed_Int16(pointer._extract)
    case .acquiring:
      return _sa_load_acquire_Int16(pointer._extract)
    case .sequentiallyConsistent:
      return _sa_load_seq_cst_Int16(pointer._extract)
    default:
      fatalError("Unsupported ordering")
    }
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicStore(
    _ desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicStoreOrdering
  ) {
    switch ordering {
    case .relaxed:
      _sa_store_relaxed_Int16(pointer._extract, desired)
    case .releasing:
      _sa_store_release_Int16(pointer._extract, desired)
    case .sequentiallyConsistent:
      _sa_store_seq_cst_Int16(pointer._extract, desired)
    default:
      fatalError("Unsupported ordering")
    }
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicExchange(
    _ desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_exchange_relaxed_Int16(pointer._extract, desired)
    case .acquiring:
      return _sa_exchange_acquire_Int16(pointer._extract, desired)
    case .releasing:
      return _sa_exchange_release_Int16(pointer._extract, desired)
    case .acquiringAndReleasing:
      return _sa_exchange_acq_rel_Int16(pointer._extract, desired)
    case .sequentiallyConsistent:
      return _sa_exchange_seq_cst_Int16(pointer._extract, desired)
    default:
      fatalError("Unsupported ordering")
    }
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicCompareExchange(
    expected: Value,
    desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> (exchanged: Bool, original: Value) {
    var expected = expected
    let exchanged: Bool
    switch ordering {
    case .relaxed:
      exchanged = _sa_cmpxchg_strong_relaxed_relaxed_Int16(
        pointer._extract,
        &expected, desired)
    case .acquiring:
      exchanged = _sa_cmpxchg_strong_acquire_acquire_Int16(
        pointer._extract,
        &expected, desired)
    case .releasing:
      exchanged = _sa_cmpxchg_strong_release_relaxed_Int16(
        pointer._extract,
        &expected, desired)
    case .acquiringAndReleasing:
      exchanged = _sa_cmpxchg_strong_acq_rel_acquire_Int16(
        pointer._extract,
        &expected, desired)
    case .sequentiallyConsistent:
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_Int16(
        pointer._extract,
        &expected, desired)
    default:
      fatalError("Unsupported ordering")
    }
    return (exchanged, expected)
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicCompareExchange(
    expected: Value,
    desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    successOrdering: AtomicUpdateOrdering,
    failureOrdering: AtomicLoadOrdering
  ) -> (exchanged: Bool, original: Value) {
    var expected = expected
    let exchanged: Bool
    // FIXME: stdatomic.h (and LLVM underneath) doesn't support
    // arbitrary ordering combinations yet, so upgrade the success
    // ordering when necessary so that it is at least as "strong" as
    // the failure case.
    switch (successOrdering, failureOrdering) {
    case (.relaxed, .relaxed):
      exchanged = _sa_cmpxchg_strong_relaxed_relaxed_Int16(
        pointer._extract,
        &expected,
        desired)
    case (.relaxed, .acquiring):
      exchanged = _sa_cmpxchg_strong_acquire_acquire_Int16(
        pointer._extract,
        &expected,
        desired)
    case (.relaxed, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_Int16(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .relaxed):
      exchanged = _sa_cmpxchg_strong_acquire_relaxed_Int16(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .acquiring):
      exchanged = _sa_cmpxchg_strong_acquire_acquire_Int16(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_Int16(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .relaxed):
      exchanged = _sa_cmpxchg_strong_release_relaxed_Int16(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .acquiring):
      exchanged = _sa_cmpxchg_strong_acq_rel_acquire_Int16(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_Int16(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .relaxed):
      exchanged = _sa_cmpxchg_strong_acq_rel_relaxed_Int16(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .acquiring):
      exchanged = _sa_cmpxchg_strong_acq_rel_acquire_Int16(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_Int16(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .relaxed):
      exchanged = _sa_cmpxchg_strong_seq_cst_relaxed_Int16(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .acquiring):
      exchanged = _sa_cmpxchg_strong_seq_cst_acquire_Int16(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_Int16(
        pointer._extract,
        &expected,
        desired)
    default:
      fatalError("Unsupported ordering")
    }
    return (exchanged, expected)
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicWeakCompareExchange(
    expected: Value,
    desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    successOrdering: AtomicUpdateOrdering,
    failureOrdering: AtomicLoadOrdering
  ) -> (exchanged: Bool, original: Value) {
    var expected = expected
    let exchanged: Bool
    // FIXME: stdatomic.h (and LLVM underneath) doesn't support
    // arbitrary ordering combinations yet, so upgrade the success
    // ordering when necessary so that it is at least as "strong" as
    // the failure case.
    switch (successOrdering, failureOrdering) {
    case (.relaxed, .relaxed):
      exchanged = _sa_cmpxchg_weak_relaxed_relaxed_Int16(
        pointer._extract,
        &expected,
        desired)
    case (.relaxed, .acquiring):
      exchanged = _sa_cmpxchg_weak_acquire_acquire_Int16(
        pointer._extract,
        &expected,
        desired)
    case (.relaxed, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_Int16(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .relaxed):
      exchanged = _sa_cmpxchg_weak_acquire_relaxed_Int16(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .acquiring):
      exchanged = _sa_cmpxchg_weak_acquire_acquire_Int16(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_Int16(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .relaxed):
      exchanged = _sa_cmpxchg_weak_release_relaxed_Int16(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .acquiring):
      exchanged = _sa_cmpxchg_weak_acq_rel_acquire_Int16(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_Int16(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .relaxed):
      exchanged = _sa_cmpxchg_weak_acq_rel_relaxed_Int16(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .acquiring):
      exchanged = _sa_cmpxchg_weak_acq_rel_acquire_Int16(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_Int16(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .relaxed):
      exchanged = _sa_cmpxchg_weak_seq_cst_relaxed_Int16(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .acquiring):
      exchanged = _sa_cmpxchg_weak_seq_cst_acquire_Int16(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_Int16(
        pointer._extract,
        &expected,
        desired)
    default:
      fatalError("Unsupported ordering")
    }
    return (exchanged, expected)
  }
}

extension Int16: AtomicInteger {}

extension Int16.AtomicRepresentation: AtomicIntegerStorage {
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenWrappingIncrement(
    by operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_add_relaxed_Int16(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_add_acquire_Int16(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_add_release_Int16(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_add_acq_rel_Int16(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_add_seq_cst_Int16(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenWrappingDecrement(
    by operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_sub_relaxed_Int16(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_sub_acquire_Int16(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_sub_release_Int16(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_sub_acq_rel_Int16(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_sub_seq_cst_Int16(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenBitwiseAnd(
    with operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_and_relaxed_Int16(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_and_acquire_Int16(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_and_release_Int16(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_and_acq_rel_Int16(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_and_seq_cst_Int16(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenBitwiseOr(
    with operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_or_relaxed_Int16(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_or_acquire_Int16(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_or_release_Int16(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_or_acq_rel_Int16(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_or_seq_cst_Int16(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenBitwiseXor(
    with operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_xor_relaxed_Int16(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_xor_acquire_Int16(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_xor_release_Int16(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_xor_acq_rel_Int16(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_xor_seq_cst_Int16(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
}

extension Int8: AtomicValue {
  @frozen
  public struct AtomicRepresentation {
    public typealias Value = Int8

    @usableFromInline
    var _storage: _AtomicInt8Storage

    @inline(__always) @_alwaysEmitIntoClient
    public init(_ value: Value) {
      self._storage = _sa_prepare_Int8(value)
    }

    @inline(__always) @_alwaysEmitIntoClient
    public func dispose() -> Value {
      return _sa_dispose_Int8(_storage)
    }
  }
}

extension UnsafeMutablePointer
where Pointee == Int8.AtomicRepresentation {
  @inlinable @inline(__always)
  internal var _extract: UnsafeMutablePointer<_AtomicInt8Storage> {
    // `Int8` is layout-compatible with its only stored property.
    return UnsafeMutableRawPointer(self)
      .assumingMemoryBound(to: _AtomicInt8Storage.self)
  }
}

extension Int8.AtomicRepresentation: AtomicStorage {
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicLoad(
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicLoadOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_load_relaxed_Int8(pointer._extract)
    case .acquiring:
      return _sa_load_acquire_Int8(pointer._extract)
    case .sequentiallyConsistent:
      return _sa_load_seq_cst_Int8(pointer._extract)
    default:
      fatalError("Unsupported ordering")
    }
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicStore(
    _ desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicStoreOrdering
  ) {
    switch ordering {
    case .relaxed:
      _sa_store_relaxed_Int8(pointer._extract, desired)
    case .releasing:
      _sa_store_release_Int8(pointer._extract, desired)
    case .sequentiallyConsistent:
      _sa_store_seq_cst_Int8(pointer._extract, desired)
    default:
      fatalError("Unsupported ordering")
    }
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicExchange(
    _ desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_exchange_relaxed_Int8(pointer._extract, desired)
    case .acquiring:
      return _sa_exchange_acquire_Int8(pointer._extract, desired)
    case .releasing:
      return _sa_exchange_release_Int8(pointer._extract, desired)
    case .acquiringAndReleasing:
      return _sa_exchange_acq_rel_Int8(pointer._extract, desired)
    case .sequentiallyConsistent:
      return _sa_exchange_seq_cst_Int8(pointer._extract, desired)
    default:
      fatalError("Unsupported ordering")
    }
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicCompareExchange(
    expected: Value,
    desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> (exchanged: Bool, original: Value) {
    var expected = expected
    let exchanged: Bool
    switch ordering {
    case .relaxed:
      exchanged = _sa_cmpxchg_strong_relaxed_relaxed_Int8(
        pointer._extract,
        &expected, desired)
    case .acquiring:
      exchanged = _sa_cmpxchg_strong_acquire_acquire_Int8(
        pointer._extract,
        &expected, desired)
    case .releasing:
      exchanged = _sa_cmpxchg_strong_release_relaxed_Int8(
        pointer._extract,
        &expected, desired)
    case .acquiringAndReleasing:
      exchanged = _sa_cmpxchg_strong_acq_rel_acquire_Int8(
        pointer._extract,
        &expected, desired)
    case .sequentiallyConsistent:
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_Int8(
        pointer._extract,
        &expected, desired)
    default:
      fatalError("Unsupported ordering")
    }
    return (exchanged, expected)
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicCompareExchange(
    expected: Value,
    desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    successOrdering: AtomicUpdateOrdering,
    failureOrdering: AtomicLoadOrdering
  ) -> (exchanged: Bool, original: Value) {
    var expected = expected
    let exchanged: Bool
    // FIXME: stdatomic.h (and LLVM underneath) doesn't support
    // arbitrary ordering combinations yet, so upgrade the success
    // ordering when necessary so that it is at least as "strong" as
    // the failure case.
    switch (successOrdering, failureOrdering) {
    case (.relaxed, .relaxed):
      exchanged = _sa_cmpxchg_strong_relaxed_relaxed_Int8(
        pointer._extract,
        &expected,
        desired)
    case (.relaxed, .acquiring):
      exchanged = _sa_cmpxchg_strong_acquire_acquire_Int8(
        pointer._extract,
        &expected,
        desired)
    case (.relaxed, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_Int8(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .relaxed):
      exchanged = _sa_cmpxchg_strong_acquire_relaxed_Int8(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .acquiring):
      exchanged = _sa_cmpxchg_strong_acquire_acquire_Int8(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_Int8(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .relaxed):
      exchanged = _sa_cmpxchg_strong_release_relaxed_Int8(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .acquiring):
      exchanged = _sa_cmpxchg_strong_acq_rel_acquire_Int8(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_Int8(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .relaxed):
      exchanged = _sa_cmpxchg_strong_acq_rel_relaxed_Int8(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .acquiring):
      exchanged = _sa_cmpxchg_strong_acq_rel_acquire_Int8(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_Int8(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .relaxed):
      exchanged = _sa_cmpxchg_strong_seq_cst_relaxed_Int8(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .acquiring):
      exchanged = _sa_cmpxchg_strong_seq_cst_acquire_Int8(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_Int8(
        pointer._extract,
        &expected,
        desired)
    default:
      fatalError("Unsupported ordering")
    }
    return (exchanged, expected)
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicWeakCompareExchange(
    expected: Value,
    desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    successOrdering: AtomicUpdateOrdering,
    failureOrdering: AtomicLoadOrdering
  ) -> (exchanged: Bool, original: Value) {
    var expected = expected
    let exchanged: Bool
    // FIXME: stdatomic.h (and LLVM underneath) doesn't support
    // arbitrary ordering combinations yet, so upgrade the success
    // ordering when necessary so that it is at least as "strong" as
    // the failure case.
    switch (successOrdering, failureOrdering) {
    case (.relaxed, .relaxed):
      exchanged = _sa_cmpxchg_weak_relaxed_relaxed_Int8(
        pointer._extract,
        &expected,
        desired)
    case (.relaxed, .acquiring):
      exchanged = _sa_cmpxchg_weak_acquire_acquire_Int8(
        pointer._extract,
        &expected,
        desired)
    case (.relaxed, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_Int8(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .relaxed):
      exchanged = _sa_cmpxchg_weak_acquire_relaxed_Int8(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .acquiring):
      exchanged = _sa_cmpxchg_weak_acquire_acquire_Int8(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_Int8(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .relaxed):
      exchanged = _sa_cmpxchg_weak_release_relaxed_Int8(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .acquiring):
      exchanged = _sa_cmpxchg_weak_acq_rel_acquire_Int8(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_Int8(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .relaxed):
      exchanged = _sa_cmpxchg_weak_acq_rel_relaxed_Int8(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .acquiring):
      exchanged = _sa_cmpxchg_weak_acq_rel_acquire_Int8(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_Int8(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .relaxed):
      exchanged = _sa_cmpxchg_weak_seq_cst_relaxed_Int8(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .acquiring):
      exchanged = _sa_cmpxchg_weak_seq_cst_acquire_Int8(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_Int8(
        pointer._extract,
        &expected,
        desired)
    default:
      fatalError("Unsupported ordering")
    }
    return (exchanged, expected)
  }
}

extension Int8: AtomicInteger {}

extension Int8.AtomicRepresentation: AtomicIntegerStorage {
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenWrappingIncrement(
    by operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_add_relaxed_Int8(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_add_acquire_Int8(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_add_release_Int8(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_add_acq_rel_Int8(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_add_seq_cst_Int8(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenWrappingDecrement(
    by operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_sub_relaxed_Int8(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_sub_acquire_Int8(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_sub_release_Int8(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_sub_acq_rel_Int8(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_sub_seq_cst_Int8(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenBitwiseAnd(
    with operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_and_relaxed_Int8(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_and_acquire_Int8(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_and_release_Int8(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_and_acq_rel_Int8(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_and_seq_cst_Int8(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenBitwiseOr(
    with operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_or_relaxed_Int8(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_or_acquire_Int8(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_or_release_Int8(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_or_acq_rel_Int8(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_or_seq_cst_Int8(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenBitwiseXor(
    with operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_xor_relaxed_Int8(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_xor_acquire_Int8(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_xor_release_Int8(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_xor_acq_rel_Int8(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_xor_seq_cst_Int8(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
}

extension UInt: AtomicValue {
  @frozen
  public struct AtomicRepresentation {
    public typealias Value = UInt

    @usableFromInline
    var _storage: _AtomicUIntStorage

    @inline(__always) @_alwaysEmitIntoClient
    public init(_ value: Value) {
      self._storage = _sa_prepare_UInt(value)
    }

    @inline(__always) @_alwaysEmitIntoClient
    public func dispose() -> Value {
      return _sa_dispose_UInt(_storage)
    }
  }
}

extension UnsafeMutablePointer
where Pointee == UInt.AtomicRepresentation {
  @inlinable @inline(__always)
  internal var _extract: UnsafeMutablePointer<_AtomicUIntStorage> {
    // `UInt` is layout-compatible with its only stored property.
    return UnsafeMutableRawPointer(self)
      .assumingMemoryBound(to: _AtomicUIntStorage.self)
  }
}

extension UInt.AtomicRepresentation: AtomicStorage {
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicLoad(
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicLoadOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_load_relaxed_UInt(pointer._extract)
    case .acquiring:
      return _sa_load_acquire_UInt(pointer._extract)
    case .sequentiallyConsistent:
      return _sa_load_seq_cst_UInt(pointer._extract)
    default:
      fatalError("Unsupported ordering")
    }
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicStore(
    _ desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicStoreOrdering
  ) {
    switch ordering {
    case .relaxed:
      _sa_store_relaxed_UInt(pointer._extract, desired)
    case .releasing:
      _sa_store_release_UInt(pointer._extract, desired)
    case .sequentiallyConsistent:
      _sa_store_seq_cst_UInt(pointer._extract, desired)
    default:
      fatalError("Unsupported ordering")
    }
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicExchange(
    _ desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_exchange_relaxed_UInt(pointer._extract, desired)
    case .acquiring:
      return _sa_exchange_acquire_UInt(pointer._extract, desired)
    case .releasing:
      return _sa_exchange_release_UInt(pointer._extract, desired)
    case .acquiringAndReleasing:
      return _sa_exchange_acq_rel_UInt(pointer._extract, desired)
    case .sequentiallyConsistent:
      return _sa_exchange_seq_cst_UInt(pointer._extract, desired)
    default:
      fatalError("Unsupported ordering")
    }
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicCompareExchange(
    expected: Value,
    desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> (exchanged: Bool, original: Value) {
    var expected = expected
    let exchanged: Bool
    switch ordering {
    case .relaxed:
      exchanged = _sa_cmpxchg_strong_relaxed_relaxed_UInt(
        pointer._extract,
        &expected, desired)
    case .acquiring:
      exchanged = _sa_cmpxchg_strong_acquire_acquire_UInt(
        pointer._extract,
        &expected, desired)
    case .releasing:
      exchanged = _sa_cmpxchg_strong_release_relaxed_UInt(
        pointer._extract,
        &expected, desired)
    case .acquiringAndReleasing:
      exchanged = _sa_cmpxchg_strong_acq_rel_acquire_UInt(
        pointer._extract,
        &expected, desired)
    case .sequentiallyConsistent:
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_UInt(
        pointer._extract,
        &expected, desired)
    default:
      fatalError("Unsupported ordering")
    }
    return (exchanged, expected)
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicCompareExchange(
    expected: Value,
    desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    successOrdering: AtomicUpdateOrdering,
    failureOrdering: AtomicLoadOrdering
  ) -> (exchanged: Bool, original: Value) {
    var expected = expected
    let exchanged: Bool
    // FIXME: stdatomic.h (and LLVM underneath) doesn't support
    // arbitrary ordering combinations yet, so upgrade the success
    // ordering when necessary so that it is at least as "strong" as
    // the failure case.
    switch (successOrdering, failureOrdering) {
    case (.relaxed, .relaxed):
      exchanged = _sa_cmpxchg_strong_relaxed_relaxed_UInt(
        pointer._extract,
        &expected,
        desired)
    case (.relaxed, .acquiring):
      exchanged = _sa_cmpxchg_strong_acquire_acquire_UInt(
        pointer._extract,
        &expected,
        desired)
    case (.relaxed, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_UInt(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .relaxed):
      exchanged = _sa_cmpxchg_strong_acquire_relaxed_UInt(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .acquiring):
      exchanged = _sa_cmpxchg_strong_acquire_acquire_UInt(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_UInt(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .relaxed):
      exchanged = _sa_cmpxchg_strong_release_relaxed_UInt(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .acquiring):
      exchanged = _sa_cmpxchg_strong_acq_rel_acquire_UInt(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_UInt(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .relaxed):
      exchanged = _sa_cmpxchg_strong_acq_rel_relaxed_UInt(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .acquiring):
      exchanged = _sa_cmpxchg_strong_acq_rel_acquire_UInt(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_UInt(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .relaxed):
      exchanged = _sa_cmpxchg_strong_seq_cst_relaxed_UInt(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .acquiring):
      exchanged = _sa_cmpxchg_strong_seq_cst_acquire_UInt(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_UInt(
        pointer._extract,
        &expected,
        desired)
    default:
      fatalError("Unsupported ordering")
    }
    return (exchanged, expected)
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicWeakCompareExchange(
    expected: Value,
    desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    successOrdering: AtomicUpdateOrdering,
    failureOrdering: AtomicLoadOrdering
  ) -> (exchanged: Bool, original: Value) {
    var expected = expected
    let exchanged: Bool
    // FIXME: stdatomic.h (and LLVM underneath) doesn't support
    // arbitrary ordering combinations yet, so upgrade the success
    // ordering when necessary so that it is at least as "strong" as
    // the failure case.
    switch (successOrdering, failureOrdering) {
    case (.relaxed, .relaxed):
      exchanged = _sa_cmpxchg_weak_relaxed_relaxed_UInt(
        pointer._extract,
        &expected,
        desired)
    case (.relaxed, .acquiring):
      exchanged = _sa_cmpxchg_weak_acquire_acquire_UInt(
        pointer._extract,
        &expected,
        desired)
    case (.relaxed, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_UInt(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .relaxed):
      exchanged = _sa_cmpxchg_weak_acquire_relaxed_UInt(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .acquiring):
      exchanged = _sa_cmpxchg_weak_acquire_acquire_UInt(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_UInt(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .relaxed):
      exchanged = _sa_cmpxchg_weak_release_relaxed_UInt(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .acquiring):
      exchanged = _sa_cmpxchg_weak_acq_rel_acquire_UInt(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_UInt(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .relaxed):
      exchanged = _sa_cmpxchg_weak_acq_rel_relaxed_UInt(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .acquiring):
      exchanged = _sa_cmpxchg_weak_acq_rel_acquire_UInt(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_UInt(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .relaxed):
      exchanged = _sa_cmpxchg_weak_seq_cst_relaxed_UInt(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .acquiring):
      exchanged = _sa_cmpxchg_weak_seq_cst_acquire_UInt(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_UInt(
        pointer._extract,
        &expected,
        desired)
    default:
      fatalError("Unsupported ordering")
    }
    return (exchanged, expected)
  }
}

extension UInt: AtomicInteger {}

extension UInt.AtomicRepresentation: AtomicIntegerStorage {
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenWrappingIncrement(
    by operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_add_relaxed_UInt(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_add_acquire_UInt(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_add_release_UInt(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_add_acq_rel_UInt(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_add_seq_cst_UInt(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenWrappingDecrement(
    by operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_sub_relaxed_UInt(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_sub_acquire_UInt(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_sub_release_UInt(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_sub_acq_rel_UInt(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_sub_seq_cst_UInt(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenBitwiseAnd(
    with operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_and_relaxed_UInt(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_and_acquire_UInt(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_and_release_UInt(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_and_acq_rel_UInt(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_and_seq_cst_UInt(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenBitwiseOr(
    with operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_or_relaxed_UInt(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_or_acquire_UInt(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_or_release_UInt(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_or_acq_rel_UInt(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_or_seq_cst_UInt(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenBitwiseXor(
    with operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_xor_relaxed_UInt(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_xor_acquire_UInt(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_xor_release_UInt(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_xor_acq_rel_UInt(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_xor_seq_cst_UInt(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
}

extension UInt64: AtomicValue {
  @frozen
  public struct AtomicRepresentation {
    public typealias Value = UInt64

    @usableFromInline
    var _storage: _AtomicUInt64Storage

    @inline(__always) @_alwaysEmitIntoClient
    public init(_ value: Value) {
      self._storage = _sa_prepare_UInt64(value)
    }

    @inline(__always) @_alwaysEmitIntoClient
    public func dispose() -> Value {
      return _sa_dispose_UInt64(_storage)
    }
  }
}

extension UnsafeMutablePointer
where Pointee == UInt64.AtomicRepresentation {
  @inlinable @inline(__always)
  internal var _extract: UnsafeMutablePointer<_AtomicUInt64Storage> {
    // `UInt64` is layout-compatible with its only stored property.
    return UnsafeMutableRawPointer(self)
      .assumingMemoryBound(to: _AtomicUInt64Storage.self)
  }
}

extension UInt64.AtomicRepresentation: AtomicStorage {
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicLoad(
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicLoadOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_load_relaxed_UInt64(pointer._extract)
    case .acquiring:
      return _sa_load_acquire_UInt64(pointer._extract)
    case .sequentiallyConsistent:
      return _sa_load_seq_cst_UInt64(pointer._extract)
    default:
      fatalError("Unsupported ordering")
    }
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicStore(
    _ desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicStoreOrdering
  ) {
    switch ordering {
    case .relaxed:
      _sa_store_relaxed_UInt64(pointer._extract, desired)
    case .releasing:
      _sa_store_release_UInt64(pointer._extract, desired)
    case .sequentiallyConsistent:
      _sa_store_seq_cst_UInt64(pointer._extract, desired)
    default:
      fatalError("Unsupported ordering")
    }
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicExchange(
    _ desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_exchange_relaxed_UInt64(pointer._extract, desired)
    case .acquiring:
      return _sa_exchange_acquire_UInt64(pointer._extract, desired)
    case .releasing:
      return _sa_exchange_release_UInt64(pointer._extract, desired)
    case .acquiringAndReleasing:
      return _sa_exchange_acq_rel_UInt64(pointer._extract, desired)
    case .sequentiallyConsistent:
      return _sa_exchange_seq_cst_UInt64(pointer._extract, desired)
    default:
      fatalError("Unsupported ordering")
    }
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicCompareExchange(
    expected: Value,
    desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> (exchanged: Bool, original: Value) {
    var expected = expected
    let exchanged: Bool
    switch ordering {
    case .relaxed:
      exchanged = _sa_cmpxchg_strong_relaxed_relaxed_UInt64(
        pointer._extract,
        &expected, desired)
    case .acquiring:
      exchanged = _sa_cmpxchg_strong_acquire_acquire_UInt64(
        pointer._extract,
        &expected, desired)
    case .releasing:
      exchanged = _sa_cmpxchg_strong_release_relaxed_UInt64(
        pointer._extract,
        &expected, desired)
    case .acquiringAndReleasing:
      exchanged = _sa_cmpxchg_strong_acq_rel_acquire_UInt64(
        pointer._extract,
        &expected, desired)
    case .sequentiallyConsistent:
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_UInt64(
        pointer._extract,
        &expected, desired)
    default:
      fatalError("Unsupported ordering")
    }
    return (exchanged, expected)
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicCompareExchange(
    expected: Value,
    desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    successOrdering: AtomicUpdateOrdering,
    failureOrdering: AtomicLoadOrdering
  ) -> (exchanged: Bool, original: Value) {
    var expected = expected
    let exchanged: Bool
    // FIXME: stdatomic.h (and LLVM underneath) doesn't support
    // arbitrary ordering combinations yet, so upgrade the success
    // ordering when necessary so that it is at least as "strong" as
    // the failure case.
    switch (successOrdering, failureOrdering) {
    case (.relaxed, .relaxed):
      exchanged = _sa_cmpxchg_strong_relaxed_relaxed_UInt64(
        pointer._extract,
        &expected,
        desired)
    case (.relaxed, .acquiring):
      exchanged = _sa_cmpxchg_strong_acquire_acquire_UInt64(
        pointer._extract,
        &expected,
        desired)
    case (.relaxed, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_UInt64(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .relaxed):
      exchanged = _sa_cmpxchg_strong_acquire_relaxed_UInt64(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .acquiring):
      exchanged = _sa_cmpxchg_strong_acquire_acquire_UInt64(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_UInt64(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .relaxed):
      exchanged = _sa_cmpxchg_strong_release_relaxed_UInt64(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .acquiring):
      exchanged = _sa_cmpxchg_strong_acq_rel_acquire_UInt64(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_UInt64(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .relaxed):
      exchanged = _sa_cmpxchg_strong_acq_rel_relaxed_UInt64(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .acquiring):
      exchanged = _sa_cmpxchg_strong_acq_rel_acquire_UInt64(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_UInt64(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .relaxed):
      exchanged = _sa_cmpxchg_strong_seq_cst_relaxed_UInt64(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .acquiring):
      exchanged = _sa_cmpxchg_strong_seq_cst_acquire_UInt64(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_UInt64(
        pointer._extract,
        &expected,
        desired)
    default:
      fatalError("Unsupported ordering")
    }
    return (exchanged, expected)
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicWeakCompareExchange(
    expected: Value,
    desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    successOrdering: AtomicUpdateOrdering,
    failureOrdering: AtomicLoadOrdering
  ) -> (exchanged: Bool, original: Value) {
    var expected = expected
    let exchanged: Bool
    // FIXME: stdatomic.h (and LLVM underneath) doesn't support
    // arbitrary ordering combinations yet, so upgrade the success
    // ordering when necessary so that it is at least as "strong" as
    // the failure case.
    switch (successOrdering, failureOrdering) {
    case (.relaxed, .relaxed):
      exchanged = _sa_cmpxchg_weak_relaxed_relaxed_UInt64(
        pointer._extract,
        &expected,
        desired)
    case (.relaxed, .acquiring):
      exchanged = _sa_cmpxchg_weak_acquire_acquire_UInt64(
        pointer._extract,
        &expected,
        desired)
    case (.relaxed, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_UInt64(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .relaxed):
      exchanged = _sa_cmpxchg_weak_acquire_relaxed_UInt64(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .acquiring):
      exchanged = _sa_cmpxchg_weak_acquire_acquire_UInt64(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_UInt64(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .relaxed):
      exchanged = _sa_cmpxchg_weak_release_relaxed_UInt64(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .acquiring):
      exchanged = _sa_cmpxchg_weak_acq_rel_acquire_UInt64(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_UInt64(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .relaxed):
      exchanged = _sa_cmpxchg_weak_acq_rel_relaxed_UInt64(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .acquiring):
      exchanged = _sa_cmpxchg_weak_acq_rel_acquire_UInt64(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_UInt64(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .relaxed):
      exchanged = _sa_cmpxchg_weak_seq_cst_relaxed_UInt64(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .acquiring):
      exchanged = _sa_cmpxchg_weak_seq_cst_acquire_UInt64(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_UInt64(
        pointer._extract,
        &expected,
        desired)
    default:
      fatalError("Unsupported ordering")
    }
    return (exchanged, expected)
  }
}

extension UInt64: AtomicInteger {}

extension UInt64.AtomicRepresentation: AtomicIntegerStorage {
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenWrappingIncrement(
    by operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_add_relaxed_UInt64(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_add_acquire_UInt64(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_add_release_UInt64(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_add_acq_rel_UInt64(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_add_seq_cst_UInt64(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenWrappingDecrement(
    by operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_sub_relaxed_UInt64(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_sub_acquire_UInt64(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_sub_release_UInt64(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_sub_acq_rel_UInt64(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_sub_seq_cst_UInt64(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenBitwiseAnd(
    with operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_and_relaxed_UInt64(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_and_acquire_UInt64(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_and_release_UInt64(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_and_acq_rel_UInt64(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_and_seq_cst_UInt64(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenBitwiseOr(
    with operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_or_relaxed_UInt64(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_or_acquire_UInt64(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_or_release_UInt64(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_or_acq_rel_UInt64(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_or_seq_cst_UInt64(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenBitwiseXor(
    with operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_xor_relaxed_UInt64(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_xor_acquire_UInt64(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_xor_release_UInt64(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_xor_acq_rel_UInt64(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_xor_seq_cst_UInt64(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
}

extension UInt32: AtomicValue {
  @frozen
  public struct AtomicRepresentation {
    public typealias Value = UInt32

    @usableFromInline
    var _storage: _AtomicUInt32Storage

    @inline(__always) @_alwaysEmitIntoClient
    public init(_ value: Value) {
      self._storage = _sa_prepare_UInt32(value)
    }

    @inline(__always) @_alwaysEmitIntoClient
    public func dispose() -> Value {
      return _sa_dispose_UInt32(_storage)
    }
  }
}

extension UnsafeMutablePointer
where Pointee == UInt32.AtomicRepresentation {
  @inlinable @inline(__always)
  internal var _extract: UnsafeMutablePointer<_AtomicUInt32Storage> {
    // `UInt32` is layout-compatible with its only stored property.
    return UnsafeMutableRawPointer(self)
      .assumingMemoryBound(to: _AtomicUInt32Storage.self)
  }
}

extension UInt32.AtomicRepresentation: AtomicStorage {
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicLoad(
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicLoadOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_load_relaxed_UInt32(pointer._extract)
    case .acquiring:
      return _sa_load_acquire_UInt32(pointer._extract)
    case .sequentiallyConsistent:
      return _sa_load_seq_cst_UInt32(pointer._extract)
    default:
      fatalError("Unsupported ordering")
    }
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicStore(
    _ desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicStoreOrdering
  ) {
    switch ordering {
    case .relaxed:
      _sa_store_relaxed_UInt32(pointer._extract, desired)
    case .releasing:
      _sa_store_release_UInt32(pointer._extract, desired)
    case .sequentiallyConsistent:
      _sa_store_seq_cst_UInt32(pointer._extract, desired)
    default:
      fatalError("Unsupported ordering")
    }
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicExchange(
    _ desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_exchange_relaxed_UInt32(pointer._extract, desired)
    case .acquiring:
      return _sa_exchange_acquire_UInt32(pointer._extract, desired)
    case .releasing:
      return _sa_exchange_release_UInt32(pointer._extract, desired)
    case .acquiringAndReleasing:
      return _sa_exchange_acq_rel_UInt32(pointer._extract, desired)
    case .sequentiallyConsistent:
      return _sa_exchange_seq_cst_UInt32(pointer._extract, desired)
    default:
      fatalError("Unsupported ordering")
    }
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicCompareExchange(
    expected: Value,
    desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> (exchanged: Bool, original: Value) {
    var expected = expected
    let exchanged: Bool
    switch ordering {
    case .relaxed:
      exchanged = _sa_cmpxchg_strong_relaxed_relaxed_UInt32(
        pointer._extract,
        &expected, desired)
    case .acquiring:
      exchanged = _sa_cmpxchg_strong_acquire_acquire_UInt32(
        pointer._extract,
        &expected, desired)
    case .releasing:
      exchanged = _sa_cmpxchg_strong_release_relaxed_UInt32(
        pointer._extract,
        &expected, desired)
    case .acquiringAndReleasing:
      exchanged = _sa_cmpxchg_strong_acq_rel_acquire_UInt32(
        pointer._extract,
        &expected, desired)
    case .sequentiallyConsistent:
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_UInt32(
        pointer._extract,
        &expected, desired)
    default:
      fatalError("Unsupported ordering")
    }
    return (exchanged, expected)
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicCompareExchange(
    expected: Value,
    desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    successOrdering: AtomicUpdateOrdering,
    failureOrdering: AtomicLoadOrdering
  ) -> (exchanged: Bool, original: Value) {
    var expected = expected
    let exchanged: Bool
    // FIXME: stdatomic.h (and LLVM underneath) doesn't support
    // arbitrary ordering combinations yet, so upgrade the success
    // ordering when necessary so that it is at least as "strong" as
    // the failure case.
    switch (successOrdering, failureOrdering) {
    case (.relaxed, .relaxed):
      exchanged = _sa_cmpxchg_strong_relaxed_relaxed_UInt32(
        pointer._extract,
        &expected,
        desired)
    case (.relaxed, .acquiring):
      exchanged = _sa_cmpxchg_strong_acquire_acquire_UInt32(
        pointer._extract,
        &expected,
        desired)
    case (.relaxed, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_UInt32(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .relaxed):
      exchanged = _sa_cmpxchg_strong_acquire_relaxed_UInt32(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .acquiring):
      exchanged = _sa_cmpxchg_strong_acquire_acquire_UInt32(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_UInt32(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .relaxed):
      exchanged = _sa_cmpxchg_strong_release_relaxed_UInt32(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .acquiring):
      exchanged = _sa_cmpxchg_strong_acq_rel_acquire_UInt32(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_UInt32(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .relaxed):
      exchanged = _sa_cmpxchg_strong_acq_rel_relaxed_UInt32(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .acquiring):
      exchanged = _sa_cmpxchg_strong_acq_rel_acquire_UInt32(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_UInt32(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .relaxed):
      exchanged = _sa_cmpxchg_strong_seq_cst_relaxed_UInt32(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .acquiring):
      exchanged = _sa_cmpxchg_strong_seq_cst_acquire_UInt32(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_UInt32(
        pointer._extract,
        &expected,
        desired)
    default:
      fatalError("Unsupported ordering")
    }
    return (exchanged, expected)
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicWeakCompareExchange(
    expected: Value,
    desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    successOrdering: AtomicUpdateOrdering,
    failureOrdering: AtomicLoadOrdering
  ) -> (exchanged: Bool, original: Value) {
    var expected = expected
    let exchanged: Bool
    // FIXME: stdatomic.h (and LLVM underneath) doesn't support
    // arbitrary ordering combinations yet, so upgrade the success
    // ordering when necessary so that it is at least as "strong" as
    // the failure case.
    switch (successOrdering, failureOrdering) {
    case (.relaxed, .relaxed):
      exchanged = _sa_cmpxchg_weak_relaxed_relaxed_UInt32(
        pointer._extract,
        &expected,
        desired)
    case (.relaxed, .acquiring):
      exchanged = _sa_cmpxchg_weak_acquire_acquire_UInt32(
        pointer._extract,
        &expected,
        desired)
    case (.relaxed, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_UInt32(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .relaxed):
      exchanged = _sa_cmpxchg_weak_acquire_relaxed_UInt32(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .acquiring):
      exchanged = _sa_cmpxchg_weak_acquire_acquire_UInt32(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_UInt32(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .relaxed):
      exchanged = _sa_cmpxchg_weak_release_relaxed_UInt32(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .acquiring):
      exchanged = _sa_cmpxchg_weak_acq_rel_acquire_UInt32(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_UInt32(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .relaxed):
      exchanged = _sa_cmpxchg_weak_acq_rel_relaxed_UInt32(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .acquiring):
      exchanged = _sa_cmpxchg_weak_acq_rel_acquire_UInt32(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_UInt32(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .relaxed):
      exchanged = _sa_cmpxchg_weak_seq_cst_relaxed_UInt32(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .acquiring):
      exchanged = _sa_cmpxchg_weak_seq_cst_acquire_UInt32(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_UInt32(
        pointer._extract,
        &expected,
        desired)
    default:
      fatalError("Unsupported ordering")
    }
    return (exchanged, expected)
  }
}

extension UInt32: AtomicInteger {}

extension UInt32.AtomicRepresentation: AtomicIntegerStorage {
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenWrappingIncrement(
    by operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_add_relaxed_UInt32(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_add_acquire_UInt32(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_add_release_UInt32(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_add_acq_rel_UInt32(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_add_seq_cst_UInt32(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenWrappingDecrement(
    by operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_sub_relaxed_UInt32(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_sub_acquire_UInt32(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_sub_release_UInt32(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_sub_acq_rel_UInt32(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_sub_seq_cst_UInt32(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenBitwiseAnd(
    with operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_and_relaxed_UInt32(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_and_acquire_UInt32(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_and_release_UInt32(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_and_acq_rel_UInt32(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_and_seq_cst_UInt32(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenBitwiseOr(
    with operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_or_relaxed_UInt32(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_or_acquire_UInt32(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_or_release_UInt32(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_or_acq_rel_UInt32(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_or_seq_cst_UInt32(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenBitwiseXor(
    with operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_xor_relaxed_UInt32(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_xor_acquire_UInt32(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_xor_release_UInt32(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_xor_acq_rel_UInt32(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_xor_seq_cst_UInt32(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
}

extension UInt16: AtomicValue {
  @frozen
  public struct AtomicRepresentation {
    public typealias Value = UInt16

    @usableFromInline
    var _storage: _AtomicUInt16Storage

    @inline(__always) @_alwaysEmitIntoClient
    public init(_ value: Value) {
      self._storage = _sa_prepare_UInt16(value)
    }

    @inline(__always) @_alwaysEmitIntoClient
    public func dispose() -> Value {
      return _sa_dispose_UInt16(_storage)
    }
  }
}

extension UnsafeMutablePointer
where Pointee == UInt16.AtomicRepresentation {
  @inlinable @inline(__always)
  internal var _extract: UnsafeMutablePointer<_AtomicUInt16Storage> {
    // `UInt16` is layout-compatible with its only stored property.
    return UnsafeMutableRawPointer(self)
      .assumingMemoryBound(to: _AtomicUInt16Storage.self)
  }
}

extension UInt16.AtomicRepresentation: AtomicStorage {
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicLoad(
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicLoadOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_load_relaxed_UInt16(pointer._extract)
    case .acquiring:
      return _sa_load_acquire_UInt16(pointer._extract)
    case .sequentiallyConsistent:
      return _sa_load_seq_cst_UInt16(pointer._extract)
    default:
      fatalError("Unsupported ordering")
    }
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicStore(
    _ desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicStoreOrdering
  ) {
    switch ordering {
    case .relaxed:
      _sa_store_relaxed_UInt16(pointer._extract, desired)
    case .releasing:
      _sa_store_release_UInt16(pointer._extract, desired)
    case .sequentiallyConsistent:
      _sa_store_seq_cst_UInt16(pointer._extract, desired)
    default:
      fatalError("Unsupported ordering")
    }
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicExchange(
    _ desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_exchange_relaxed_UInt16(pointer._extract, desired)
    case .acquiring:
      return _sa_exchange_acquire_UInt16(pointer._extract, desired)
    case .releasing:
      return _sa_exchange_release_UInt16(pointer._extract, desired)
    case .acquiringAndReleasing:
      return _sa_exchange_acq_rel_UInt16(pointer._extract, desired)
    case .sequentiallyConsistent:
      return _sa_exchange_seq_cst_UInt16(pointer._extract, desired)
    default:
      fatalError("Unsupported ordering")
    }
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicCompareExchange(
    expected: Value,
    desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> (exchanged: Bool, original: Value) {
    var expected = expected
    let exchanged: Bool
    switch ordering {
    case .relaxed:
      exchanged = _sa_cmpxchg_strong_relaxed_relaxed_UInt16(
        pointer._extract,
        &expected, desired)
    case .acquiring:
      exchanged = _sa_cmpxchg_strong_acquire_acquire_UInt16(
        pointer._extract,
        &expected, desired)
    case .releasing:
      exchanged = _sa_cmpxchg_strong_release_relaxed_UInt16(
        pointer._extract,
        &expected, desired)
    case .acquiringAndReleasing:
      exchanged = _sa_cmpxchg_strong_acq_rel_acquire_UInt16(
        pointer._extract,
        &expected, desired)
    case .sequentiallyConsistent:
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_UInt16(
        pointer._extract,
        &expected, desired)
    default:
      fatalError("Unsupported ordering")
    }
    return (exchanged, expected)
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicCompareExchange(
    expected: Value,
    desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    successOrdering: AtomicUpdateOrdering,
    failureOrdering: AtomicLoadOrdering
  ) -> (exchanged: Bool, original: Value) {
    var expected = expected
    let exchanged: Bool
    // FIXME: stdatomic.h (and LLVM underneath) doesn't support
    // arbitrary ordering combinations yet, so upgrade the success
    // ordering when necessary so that it is at least as "strong" as
    // the failure case.
    switch (successOrdering, failureOrdering) {
    case (.relaxed, .relaxed):
      exchanged = _sa_cmpxchg_strong_relaxed_relaxed_UInt16(
        pointer._extract,
        &expected,
        desired)
    case (.relaxed, .acquiring):
      exchanged = _sa_cmpxchg_strong_acquire_acquire_UInt16(
        pointer._extract,
        &expected,
        desired)
    case (.relaxed, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_UInt16(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .relaxed):
      exchanged = _sa_cmpxchg_strong_acquire_relaxed_UInt16(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .acquiring):
      exchanged = _sa_cmpxchg_strong_acquire_acquire_UInt16(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_UInt16(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .relaxed):
      exchanged = _sa_cmpxchg_strong_release_relaxed_UInt16(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .acquiring):
      exchanged = _sa_cmpxchg_strong_acq_rel_acquire_UInt16(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_UInt16(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .relaxed):
      exchanged = _sa_cmpxchg_strong_acq_rel_relaxed_UInt16(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .acquiring):
      exchanged = _sa_cmpxchg_strong_acq_rel_acquire_UInt16(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_UInt16(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .relaxed):
      exchanged = _sa_cmpxchg_strong_seq_cst_relaxed_UInt16(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .acquiring):
      exchanged = _sa_cmpxchg_strong_seq_cst_acquire_UInt16(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_UInt16(
        pointer._extract,
        &expected,
        desired)
    default:
      fatalError("Unsupported ordering")
    }
    return (exchanged, expected)
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicWeakCompareExchange(
    expected: Value,
    desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    successOrdering: AtomicUpdateOrdering,
    failureOrdering: AtomicLoadOrdering
  ) -> (exchanged: Bool, original: Value) {
    var expected = expected
    let exchanged: Bool
    // FIXME: stdatomic.h (and LLVM underneath) doesn't support
    // arbitrary ordering combinations yet, so upgrade the success
    // ordering when necessary so that it is at least as "strong" as
    // the failure case.
    switch (successOrdering, failureOrdering) {
    case (.relaxed, .relaxed):
      exchanged = _sa_cmpxchg_weak_relaxed_relaxed_UInt16(
        pointer._extract,
        &expected,
        desired)
    case (.relaxed, .acquiring):
      exchanged = _sa_cmpxchg_weak_acquire_acquire_UInt16(
        pointer._extract,
        &expected,
        desired)
    case (.relaxed, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_UInt16(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .relaxed):
      exchanged = _sa_cmpxchg_weak_acquire_relaxed_UInt16(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .acquiring):
      exchanged = _sa_cmpxchg_weak_acquire_acquire_UInt16(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_UInt16(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .relaxed):
      exchanged = _sa_cmpxchg_weak_release_relaxed_UInt16(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .acquiring):
      exchanged = _sa_cmpxchg_weak_acq_rel_acquire_UInt16(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_UInt16(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .relaxed):
      exchanged = _sa_cmpxchg_weak_acq_rel_relaxed_UInt16(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .acquiring):
      exchanged = _sa_cmpxchg_weak_acq_rel_acquire_UInt16(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_UInt16(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .relaxed):
      exchanged = _sa_cmpxchg_weak_seq_cst_relaxed_UInt16(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .acquiring):
      exchanged = _sa_cmpxchg_weak_seq_cst_acquire_UInt16(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_UInt16(
        pointer._extract,
        &expected,
        desired)
    default:
      fatalError("Unsupported ordering")
    }
    return (exchanged, expected)
  }
}

extension UInt16: AtomicInteger {}

extension UInt16.AtomicRepresentation: AtomicIntegerStorage {
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenWrappingIncrement(
    by operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_add_relaxed_UInt16(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_add_acquire_UInt16(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_add_release_UInt16(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_add_acq_rel_UInt16(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_add_seq_cst_UInt16(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenWrappingDecrement(
    by operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_sub_relaxed_UInt16(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_sub_acquire_UInt16(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_sub_release_UInt16(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_sub_acq_rel_UInt16(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_sub_seq_cst_UInt16(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenBitwiseAnd(
    with operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_and_relaxed_UInt16(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_and_acquire_UInt16(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_and_release_UInt16(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_and_acq_rel_UInt16(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_and_seq_cst_UInt16(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenBitwiseOr(
    with operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_or_relaxed_UInt16(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_or_acquire_UInt16(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_or_release_UInt16(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_or_acq_rel_UInt16(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_or_seq_cst_UInt16(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenBitwiseXor(
    with operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_xor_relaxed_UInt16(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_xor_acquire_UInt16(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_xor_release_UInt16(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_xor_acq_rel_UInt16(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_xor_seq_cst_UInt16(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
}

extension UInt8: AtomicValue {
  @frozen
  public struct AtomicRepresentation {
    public typealias Value = UInt8

    @usableFromInline
    var _storage: _AtomicUInt8Storage

    @inline(__always) @_alwaysEmitIntoClient
    public init(_ value: Value) {
      self._storage = _sa_prepare_UInt8(value)
    }

    @inline(__always) @_alwaysEmitIntoClient
    public func dispose() -> Value {
      return _sa_dispose_UInt8(_storage)
    }
  }
}

extension UnsafeMutablePointer
where Pointee == UInt8.AtomicRepresentation {
  @inlinable @inline(__always)
  internal var _extract: UnsafeMutablePointer<_AtomicUInt8Storage> {
    // `UInt8` is layout-compatible with its only stored property.
    return UnsafeMutableRawPointer(self)
      .assumingMemoryBound(to: _AtomicUInt8Storage.self)
  }
}

extension UInt8.AtomicRepresentation: AtomicStorage {
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicLoad(
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicLoadOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_load_relaxed_UInt8(pointer._extract)
    case .acquiring:
      return _sa_load_acquire_UInt8(pointer._extract)
    case .sequentiallyConsistent:
      return _sa_load_seq_cst_UInt8(pointer._extract)
    default:
      fatalError("Unsupported ordering")
    }
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicStore(
    _ desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicStoreOrdering
  ) {
    switch ordering {
    case .relaxed:
      _sa_store_relaxed_UInt8(pointer._extract, desired)
    case .releasing:
      _sa_store_release_UInt8(pointer._extract, desired)
    case .sequentiallyConsistent:
      _sa_store_seq_cst_UInt8(pointer._extract, desired)
    default:
      fatalError("Unsupported ordering")
    }
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicExchange(
    _ desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_exchange_relaxed_UInt8(pointer._extract, desired)
    case .acquiring:
      return _sa_exchange_acquire_UInt8(pointer._extract, desired)
    case .releasing:
      return _sa_exchange_release_UInt8(pointer._extract, desired)
    case .acquiringAndReleasing:
      return _sa_exchange_acq_rel_UInt8(pointer._extract, desired)
    case .sequentiallyConsistent:
      return _sa_exchange_seq_cst_UInt8(pointer._extract, desired)
    default:
      fatalError("Unsupported ordering")
    }
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicCompareExchange(
    expected: Value,
    desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> (exchanged: Bool, original: Value) {
    var expected = expected
    let exchanged: Bool
    switch ordering {
    case .relaxed:
      exchanged = _sa_cmpxchg_strong_relaxed_relaxed_UInt8(
        pointer._extract,
        &expected, desired)
    case .acquiring:
      exchanged = _sa_cmpxchg_strong_acquire_acquire_UInt8(
        pointer._extract,
        &expected, desired)
    case .releasing:
      exchanged = _sa_cmpxchg_strong_release_relaxed_UInt8(
        pointer._extract,
        &expected, desired)
    case .acquiringAndReleasing:
      exchanged = _sa_cmpxchg_strong_acq_rel_acquire_UInt8(
        pointer._extract,
        &expected, desired)
    case .sequentiallyConsistent:
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_UInt8(
        pointer._extract,
        &expected, desired)
    default:
      fatalError("Unsupported ordering")
    }
    return (exchanged, expected)
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicCompareExchange(
    expected: Value,
    desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    successOrdering: AtomicUpdateOrdering,
    failureOrdering: AtomicLoadOrdering
  ) -> (exchanged: Bool, original: Value) {
    var expected = expected
    let exchanged: Bool
    // FIXME: stdatomic.h (and LLVM underneath) doesn't support
    // arbitrary ordering combinations yet, so upgrade the success
    // ordering when necessary so that it is at least as "strong" as
    // the failure case.
    switch (successOrdering, failureOrdering) {
    case (.relaxed, .relaxed):
      exchanged = _sa_cmpxchg_strong_relaxed_relaxed_UInt8(
        pointer._extract,
        &expected,
        desired)
    case (.relaxed, .acquiring):
      exchanged = _sa_cmpxchg_strong_acquire_acquire_UInt8(
        pointer._extract,
        &expected,
        desired)
    case (.relaxed, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_UInt8(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .relaxed):
      exchanged = _sa_cmpxchg_strong_acquire_relaxed_UInt8(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .acquiring):
      exchanged = _sa_cmpxchg_strong_acquire_acquire_UInt8(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_UInt8(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .relaxed):
      exchanged = _sa_cmpxchg_strong_release_relaxed_UInt8(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .acquiring):
      exchanged = _sa_cmpxchg_strong_acq_rel_acquire_UInt8(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_UInt8(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .relaxed):
      exchanged = _sa_cmpxchg_strong_acq_rel_relaxed_UInt8(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .acquiring):
      exchanged = _sa_cmpxchg_strong_acq_rel_acquire_UInt8(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_UInt8(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .relaxed):
      exchanged = _sa_cmpxchg_strong_seq_cst_relaxed_UInt8(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .acquiring):
      exchanged = _sa_cmpxchg_strong_seq_cst_acquire_UInt8(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_UInt8(
        pointer._extract,
        &expected,
        desired)
    default:
      fatalError("Unsupported ordering")
    }
    return (exchanged, expected)
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicWeakCompareExchange(
    expected: Value,
    desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    successOrdering: AtomicUpdateOrdering,
    failureOrdering: AtomicLoadOrdering
  ) -> (exchanged: Bool, original: Value) {
    var expected = expected
    let exchanged: Bool
    // FIXME: stdatomic.h (and LLVM underneath) doesn't support
    // arbitrary ordering combinations yet, so upgrade the success
    // ordering when necessary so that it is at least as "strong" as
    // the failure case.
    switch (successOrdering, failureOrdering) {
    case (.relaxed, .relaxed):
      exchanged = _sa_cmpxchg_weak_relaxed_relaxed_UInt8(
        pointer._extract,
        &expected,
        desired)
    case (.relaxed, .acquiring):
      exchanged = _sa_cmpxchg_weak_acquire_acquire_UInt8(
        pointer._extract,
        &expected,
        desired)
    case (.relaxed, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_UInt8(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .relaxed):
      exchanged = _sa_cmpxchg_weak_acquire_relaxed_UInt8(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .acquiring):
      exchanged = _sa_cmpxchg_weak_acquire_acquire_UInt8(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_UInt8(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .relaxed):
      exchanged = _sa_cmpxchg_weak_release_relaxed_UInt8(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .acquiring):
      exchanged = _sa_cmpxchg_weak_acq_rel_acquire_UInt8(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_UInt8(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .relaxed):
      exchanged = _sa_cmpxchg_weak_acq_rel_relaxed_UInt8(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .acquiring):
      exchanged = _sa_cmpxchg_weak_acq_rel_acquire_UInt8(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_UInt8(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .relaxed):
      exchanged = _sa_cmpxchg_weak_seq_cst_relaxed_UInt8(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .acquiring):
      exchanged = _sa_cmpxchg_weak_seq_cst_acquire_UInt8(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_UInt8(
        pointer._extract,
        &expected,
        desired)
    default:
      fatalError("Unsupported ordering")
    }
    return (exchanged, expected)
  }
}

extension UInt8: AtomicInteger {}

extension UInt8.AtomicRepresentation: AtomicIntegerStorage {
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenWrappingIncrement(
    by operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_add_relaxed_UInt8(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_add_acquire_UInt8(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_add_release_UInt8(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_add_acq_rel_UInt8(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_add_seq_cst_UInt8(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenWrappingDecrement(
    by operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_sub_relaxed_UInt8(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_sub_acquire_UInt8(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_sub_release_UInt8(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_sub_acq_rel_UInt8(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_sub_seq_cst_UInt8(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenBitwiseAnd(
    with operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_and_relaxed_UInt8(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_and_acquire_UInt8(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_and_release_UInt8(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_and_acq_rel_UInt8(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_and_seq_cst_UInt8(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenBitwiseOr(
    with operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_or_relaxed_UInt8(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_or_acquire_UInt8(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_or_release_UInt8(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_or_acq_rel_UInt8(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_or_seq_cst_UInt8(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  @discardableResult
  public static func atomicLoadThenBitwiseXor(
    with operand: Value = 1,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_fetch_xor_relaxed_UInt8(
        pointer._extract,
        operand)
    case .acquiring:
      return _sa_fetch_xor_acquire_UInt8(
        pointer._extract,
        operand)
    case .releasing:
      return _sa_fetch_xor_release_UInt8(
        pointer._extract,
        operand)
    case .acquiringAndReleasing:
      return _sa_fetch_xor_acq_rel_UInt8(
        pointer._extract,
        operand)
    case .sequentiallyConsistent:
      return _sa_fetch_xor_seq_cst_UInt8(
        pointer._extract,
        operand)
    default:
      fatalError("Unsupported ordering")
    }
  }
}

// Double-wide atomic primitives on x86_64 CPUs aren't available by default
// on Linux distributions, and we cannot currently enable them automatically.
#if !(os(Linux) && arch(x86_64)) || ENABLE_DOUBLEWIDE_ATOMICS
extension DoubleWord: AtomicValue {
  @frozen
  public struct AtomicRepresentation {
    public typealias Value = DoubleWord

    @usableFromInline
    var _storage: _AtomicDoubleWordStorage

    @inline(__always) @_alwaysEmitIntoClient
    public init(_ value: Value) {
      self._storage = _sa_prepare_DoubleWord(value)
    }

    @inline(__always) @_alwaysEmitIntoClient
    public func dispose() -> Value {
      // Work around https://github.com/apple/swift-atomics/issues/41
      #if compiler(>=5.5) && arch(arm64) && DEBUG
      var copy = self // This is not great
      var expected = DoubleWord(high: 0, low: 0)
      withUnsafeMutablePointer(to: &copy) { pointer in
        _ = _sa_cmpxchg_strong_relaxed_relaxed_DoubleWord(
          pointer._extract,
          &expected,
          DoubleWord(high: 0, low: 0))
      }
      return expected
      #else
      return _sa_dispose_DoubleWord(_storage)
      #endif
    }
  }
}

extension UnsafeMutablePointer
where Pointee == DoubleWord.AtomicRepresentation {
  @inlinable @inline(__always)
  internal var _extract: UnsafeMutablePointer<_AtomicDoubleWordStorage> {
    // `DoubleWord` is layout-compatible with its only stored property.
    return UnsafeMutableRawPointer(self)
      .assumingMemoryBound(to: _AtomicDoubleWordStorage.self)
  }
}

extension DoubleWord.AtomicRepresentation: AtomicStorage {
  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicLoad(
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicLoadOrdering
  ) -> Value {
    // Work around https://github.com/apple/swift-atomics/issues/41
    #if compiler(>=5.5) && arch(arm64) && DEBUG
    let (_, original) = atomicCompareExchange(
      expected: DoubleWord(high: 0, low: 0),
      desired: DoubleWord(high: 0, low: 0),
      at: pointer,
      successOrdering: .relaxed, // Note: this relies on the FIXME below.
      failureOrdering: ordering)
    return original
    #else
    switch ordering {
    case .relaxed:
      return _sa_load_relaxed_DoubleWord(pointer._extract)
    case .acquiring:
      return _sa_load_acquire_DoubleWord(pointer._extract)
    case .sequentiallyConsistent:
      return _sa_load_seq_cst_DoubleWord(pointer._extract)
    default:
      fatalError("Unsupported ordering")
    }
    #endif
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicStore(
    _ desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicStoreOrdering
  ) {
    switch ordering {
    case .relaxed:
      _sa_store_relaxed_DoubleWord(pointer._extract, desired)
    case .releasing:
      _sa_store_release_DoubleWord(pointer._extract, desired)
    case .sequentiallyConsistent:
      _sa_store_seq_cst_DoubleWord(pointer._extract, desired)
    default:
      fatalError("Unsupported ordering")
    }
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicExchange(
    _ desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> Value {
    switch ordering {
    case .relaxed:
      return _sa_exchange_relaxed_DoubleWord(pointer._extract, desired)
    case .acquiring:
      return _sa_exchange_acquire_DoubleWord(pointer._extract, desired)
    case .releasing:
      return _sa_exchange_release_DoubleWord(pointer._extract, desired)
    case .acquiringAndReleasing:
      return _sa_exchange_acq_rel_DoubleWord(pointer._extract, desired)
    case .sequentiallyConsistent:
      return _sa_exchange_seq_cst_DoubleWord(pointer._extract, desired)
    default:
      fatalError("Unsupported ordering")
    }
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicCompareExchange(
    expected: Value,
    desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    ordering: AtomicUpdateOrdering
  ) -> (exchanged: Bool, original: Value) {
    var expected = expected
    let exchanged: Bool
    switch ordering {
    case .relaxed:
      exchanged = _sa_cmpxchg_strong_relaxed_relaxed_DoubleWord(
        pointer._extract,
        &expected, desired)
    case .acquiring:
      exchanged = _sa_cmpxchg_strong_acquire_acquire_DoubleWord(
        pointer._extract,
        &expected, desired)
    case .releasing:
      exchanged = _sa_cmpxchg_strong_release_relaxed_DoubleWord(
        pointer._extract,
        &expected, desired)
    case .acquiringAndReleasing:
      exchanged = _sa_cmpxchg_strong_acq_rel_acquire_DoubleWord(
        pointer._extract,
        &expected, desired)
    case .sequentiallyConsistent:
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_DoubleWord(
        pointer._extract,
        &expected, desired)
    default:
      fatalError("Unsupported ordering")
    }
    return (exchanged, expected)
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicCompareExchange(
    expected: Value,
    desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    successOrdering: AtomicUpdateOrdering,
    failureOrdering: AtomicLoadOrdering
  ) -> (exchanged: Bool, original: Value) {
    var expected = expected
    let exchanged: Bool
    // FIXME: stdatomic.h (and LLVM underneath) doesn't support
    // arbitrary ordering combinations yet, so upgrade the success
    // ordering when necessary so that it is at least as "strong" as
    // the failure case.
    switch (successOrdering, failureOrdering) {
    case (.relaxed, .relaxed):
      exchanged = _sa_cmpxchg_strong_relaxed_relaxed_DoubleWord(
        pointer._extract,
        &expected,
        desired)
    case (.relaxed, .acquiring):
      exchanged = _sa_cmpxchg_strong_acquire_acquire_DoubleWord(
        pointer._extract,
        &expected,
        desired)
    case (.relaxed, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_DoubleWord(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .relaxed):
      exchanged = _sa_cmpxchg_strong_acquire_relaxed_DoubleWord(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .acquiring):
      exchanged = _sa_cmpxchg_strong_acquire_acquire_DoubleWord(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_DoubleWord(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .relaxed):
      exchanged = _sa_cmpxchg_strong_release_relaxed_DoubleWord(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .acquiring):
      exchanged = _sa_cmpxchg_strong_acq_rel_acquire_DoubleWord(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_DoubleWord(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .relaxed):
      exchanged = _sa_cmpxchg_strong_acq_rel_relaxed_DoubleWord(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .acquiring):
      exchanged = _sa_cmpxchg_strong_acq_rel_acquire_DoubleWord(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_DoubleWord(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .relaxed):
      exchanged = _sa_cmpxchg_strong_seq_cst_relaxed_DoubleWord(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .acquiring):
      exchanged = _sa_cmpxchg_strong_seq_cst_acquire_DoubleWord(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_strong_seq_cst_seq_cst_DoubleWord(
        pointer._extract,
        &expected,
        desired)
    default:
      fatalError("Unsupported ordering")
    }
    return (exchanged, expected)
  }

  @_semantics("atomics.requires_constant_orderings")
  @_transparent @_alwaysEmitIntoClient
  public static func atomicWeakCompareExchange(
    expected: Value,
    desired: Value,
    at pointer: UnsafeMutablePointer<Self>,
    successOrdering: AtomicUpdateOrdering,
    failureOrdering: AtomicLoadOrdering
  ) -> (exchanged: Bool, original: Value) {
    var expected = expected
    let exchanged: Bool
    // FIXME: stdatomic.h (and LLVM underneath) doesn't support
    // arbitrary ordering combinations yet, so upgrade the success
    // ordering when necessary so that it is at least as "strong" as
    // the failure case.
    switch (successOrdering, failureOrdering) {
    case (.relaxed, .relaxed):
      exchanged = _sa_cmpxchg_weak_relaxed_relaxed_DoubleWord(
        pointer._extract,
        &expected,
        desired)
    case (.relaxed, .acquiring):
      exchanged = _sa_cmpxchg_weak_acquire_acquire_DoubleWord(
        pointer._extract,
        &expected,
        desired)
    case (.relaxed, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_DoubleWord(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .relaxed):
      exchanged = _sa_cmpxchg_weak_acquire_relaxed_DoubleWord(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .acquiring):
      exchanged = _sa_cmpxchg_weak_acquire_acquire_DoubleWord(
        pointer._extract,
        &expected,
        desired)
    case (.acquiring, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_DoubleWord(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .relaxed):
      exchanged = _sa_cmpxchg_weak_release_relaxed_DoubleWord(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .acquiring):
      exchanged = _sa_cmpxchg_weak_acq_rel_acquire_DoubleWord(
        pointer._extract,
        &expected,
        desired)
    case (.releasing, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_DoubleWord(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .relaxed):
      exchanged = _sa_cmpxchg_weak_acq_rel_relaxed_DoubleWord(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .acquiring):
      exchanged = _sa_cmpxchg_weak_acq_rel_acquire_DoubleWord(
        pointer._extract,
        &expected,
        desired)
    case (.acquiringAndReleasing, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_DoubleWord(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .relaxed):
      exchanged = _sa_cmpxchg_weak_seq_cst_relaxed_DoubleWord(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .acquiring):
      exchanged = _sa_cmpxchg_weak_seq_cst_acquire_DoubleWord(
        pointer._extract,
        &expected,
        desired)
    case (.sequentiallyConsistent, .sequentiallyConsistent):
      exchanged = _sa_cmpxchg_weak_seq_cst_seq_cst_DoubleWord(
        pointer._extract,
        &expected,
        desired)
    default:
      fatalError("Unsupported ordering")
    }
    return (exchanged, expected)
  }
}


#endif // ENABLE_DOUBLEWIDE_ATOMICS
